package aigcAdminUtils

import (
	"database/sql/driver"
	"encoding/json"
	"errors"
	"time"

	"gorm.io/gorm"
)

// 工作流输出结果
type WorkflowOutputResult struct {
	Type     WorkflowOutputType `json:"type"`
	FileName string             `json:"file_name,omitempty"`
	Width    int                `json:"width,omitempty"`
	Height   int                `json:"height,omitempty"`
	Text     string             `json:"text,omitempty"`
}

func (a *WorkflowOutputResult) Scan(value interface{}) error {
	if value == nil {
		return errors.New("type WorkflowOutputResult to []byte failed")
	}
	b, ok := value.([]byte)
	if !ok {
		return errors.New("type WorkflowOutputResult to []byte failed#2")
	}
	return json.Unmarshal(b, a)
}

// Value 实现 driver.Valuer 接口
func (a WorkflowOutputResult) Value() (driver.Value, error) {
	return json.Marshal(a)
}

type Int64Array []int64

// Scan 实现 sql.Scanner 接口
func (a *Int64Array) Scan(value interface{}) error {
	if value == nil {
		*a = nil
		return nil
	}
	b, ok := value.([]byte)
	if !ok {
		return errors.New("type assertion to []byte failed")
	}
	return json.Unmarshal(b, a)
}

// Value 实现 driver.Valuer 接口
func (a Int64Array) Value() (driver.Value, error) {
	if a == nil {
		return nil, nil
	}
	return json.Marshal(a)
}

// 工作流Status枚举
type WorkflowStatus int

const (
	WorkflowStatus_Unknow     WorkflowStatus = 0
	WorkflowStatus_NotStarted WorkflowStatus = 1
	WorkflowStatus_Processing WorkflowStatus = 2
	WorkflowStatus_Finished   WorkflowStatus = 3
	WorkflowStatus_Canceled   WorkflowStatus = 4
	WorkflowStatus_Failed     WorkflowStatus = 5
)

type WorkflowTaskParams map[string]any

func (a *WorkflowTaskParams) Scan(value interface{}) error {
	if value == nil {
		*a = nil
		return nil
	}
	b, ok := value.([]byte)
	if !ok {
		return errors.New("type WorkflowTaskParams to []byte failed")
	}
	return json.Unmarshal(b, a)
}

// Value 实现 driver.Valuer 接口
func (a WorkflowTaskParams) Value() (driver.Value, error) {
	if a == nil {
		return nil, nil
	}
	return json.Marshal(a)
}

// 工作流输出
type WorkflowOutput struct {
	Id        int64                `gorm:"column:id;type:bigint;primarykey;autoIncrement"`
	OwnerTask int64                `gorm:"not null;column:owner_task;type:bigint;index;index:ownertask_isdelete;comment:所属任务"`
	Result    WorkflowOutputResult `gorm:"not null;column:result;type:text;comment:工作流输出的成果"`
	IsDelete  int                  `gorm:"not null;default:0;column:is_delete;index;index:ownertask_isdelete;type:tinyint;comment:是否已被删除"`
	DeletedAt time.Time            `gorm:"column:deleted_at;type:TIMESTAMP"`
	CreatedAt time.Time            `gorm:"column:created_at;default:CURRENT_TIMESTAMP;type:TIMESTAMP"`
	UpdatedAt time.Time            `gorm:"column:updated_at;autoUpdateTime;type:TIMESTAMP"`
}

// 工作流任务
type WorkflowTask struct {
	Id          int64              `gorm:"column:id;type:bigint;primarykey;autoIncrement"`
	WorkflowId  int64              `gorm:"not null;column:workflow_id;type:bigint;index:workflowid_panelid_userid;index:workflowid_userid;comment:工作流id"`
	PanelId     int64              `gorm:"not null;column:panel_id;type:bigint;index:workflowid_panelid_userid;comment:面板id"`
	Params      WorkflowTaskParams `gorm:"not null;column:params;type:text;comment:参数"`
	UserId      int64              `gorm:"not null;column:user_id;type:bigint;index;index:workflowid_panelid_userid;index:workflowid_userid;comment:用户ID"`
	Status      WorkflowStatus     `gorm:"not null;column:status;type:tinyint;index;comment:任务状态1-未开始,2-进行中,3-已完成,4-已取消,5-已失败"`
	Progress    float64            `gorm:"not null;default:0;column:progress;type:float;comment:进度,如果当前是排队状态,值代表前面的人数"`
	AgentTaskID string             `gorm:"column:agent_task_id;type:varchar(100);comment:comfyui代理任务id"`
	AgentNodeId string             `gorm:"not null;column:agent_node_id;type:varchar(100);comment:comfyui代理服务节点id"`
	AgentUrl    string             `gorm:"not null;column:agent_url;type:varchar(100);comment:comfyui代理服务地址"`
	IsConfirmed int                `gorm:"not null;default:0;index;column:is_confirmed;type:tinyint;comment:是否已确认"`
	CreatedAt   time.Time          `gorm:"column:created_at;default:CURRENT_TIMESTAMP;type:TIMESTAMP"`
	UpdatedAt   time.Time          `gorm:"column:updated_at;autoUpdateTime;type:TIMESTAMP"`
	//ComfyuiApi    string             `gorm:"column:comfyui_api;type:text;comment:comfyuiApi"`
	//ComfyuiParams string             `gorm:"column:comfyui_params;type:text;comment:comfyuiParams"`
}

// 工作流面板
type WorkflowPanel struct {
	Id                    int64      `gorm:"column:id;type:bigint;primarykey;autoIncrement"`
	Name                  string     `gorm:"not null;column:name;type:varchar(100);comment:面板名称;uniqueIndex:teamid_name"`
	TeamId                int64      `gorm:"not null;column:team_id;type:bigint;index;comment:团队ID;uniqueIndex:teamid_name"`
	DisplayName           string     `gorm:"not null;column:display_name;type:varchar(20);comment:用于展示的面板名称"`
	OwnerProject          int64      `gorm:"not null;column:owner_project;type:bigint;comment:所有者项目"`
	AllowProject          Int64Array `gorm:"not null;column:allow_project;type:json;comment:可使用项目列表"`
	InstallationPackageId int64      `gorm:"not null;column:installation_package_id;type:bigint;comment:工作流安装包ID"`
	LLM                   int64      `gorm:"column:llm;type:bigint;comment:llm;comment:使用的大语言模型"`
	Lora                  int64      `gorm:"column:lora;type:bigint;comment:lora;comment:使用的lora模型"`
	Desc                  string     `gorm:"column:desc;type:text;comment:描述"`
	CreatedAt             time.Time  `gorm:"column:created_at;default:CURRENT_TIMESTAMP;type:TIMESTAMP"`
	UpdatedAt             time.Time  `gorm:"column:updated_at;autoUpdateTime;type:TIMESTAMP"`
}

// 工作流安装包
type WorkflowInstallationPackage struct {
	Id              int64              `gorm:"column:id;type:bigint;primarykey;autoIncrement"`
	PackageName     string             `gorm:"not null;column:package_name;type:varchar(100);comment:工作流安装包名称"`
	ComfyuiWorkflow string             `gorm:"not null;column:comfyui_workflow;type:mediumtext;comment:comfyui工作流内容"`
	Meta            string             `gorm:"not null;column:meta;type:text;comment:工作流元数据"`
	OutputType      WorkflowOutputType `gorm:"not null;column:output_type;type:tinyint;comment:输出类型"`
	CreatedAt       time.Time          `gorm:"column:created_at;default:CURRENT_TIMESTAMP;type:TIMESTAMP"`
	UpdatedAt       time.Time          `gorm:"column:updated_at;autoUpdateTime;type:TIMESTAMP"`
}

type TaskRaw struct {
	Id               int64              `gorm:"column:id"`
	AgentUrl         string             `gorm:"column:agent_url"`
	AgentTaskID      string             `gorm:"column:agent_task_id"`
	PanelID          int64              `gorm:"column:panel_id"`
	WorkflowID       int64              `gorm:"column:workflow_id"`
	Params           string             `gorm:"column:params"`
	Status           WorkflowStatus     `gorm:"column:status"`
	Progress         float64            `gorm:"column:progress"`
	WorkflowName     string             `gorm:"column:workflow_name"`
	PanelName        string             `gorm:"column:panel_name"`
	PanelDisplayName string             `gorm:"column:panel_display_name"`
	OutputType       WorkflowOutputType `gorm:"column:output_type"`
}

// 全局变量表
type GlobalVariable struct {
	Id    string `gorm:"column:id;type:varchar(100);primarykey"`
	Value string `gorm:"column:value;type:varchar(100)"`
}

func (GlobalVariable) TableName() string {
	return "global_variable"
}

func TaskRawSelect(db *gorm.DB) (*gorm.DB, error) {
	re := db.Table("workflow_tasks").
		Joins("JOIN workflow_panels ON workflow_tasks.panel_id = workflow_panels.id").
		Joins("LEFT JOIN workflows ON workflow_tasks.workflow_id = workflows.id").
		Joins("LEFT JOIN workflow_installation_packages ON workflow_panels.installation_package_id = workflow_installation_packages.id").
		Select(
			"workflow_tasks.agent_url,"+
				"workflow_tasks.agent_task_id,"+
				"workflow_tasks.id,"+
				"workflow_tasks.panel_id,"+
				"workflow_tasks.workflow_id,"+
				"workflow_tasks.params,"+
				"workflow_tasks.status,"+
				"workflow_tasks.progress,"+
				"workflows.name AS workflow_name,"+
				"workflow_panels.name AS panel_name,"+
				"workflow_panels.display_name AS panel_display_name",
			"workflow_installation_packages.output_type",
		)

	if re.Error != nil {
		return nil, re.Error
	}
	return re, nil
}
